#ifndef __HJ_QSCOM_H__
#define __HJ_QSCOM_H__

#include <QMap>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <memory>
#include <QTimer>

class qscom : public QSerialPort
{
    Q_OBJECT
public:
    qscom(QObject *parent = nullptr) : QSerialPort(parent) {}
    ~qscom()
    {
        disc();
    }
    qscom(const QString &name, QObject *parent = nullptr)
        : QSerialPort(name, parent)
    {
        conn();
    }
    qscom(const QSerialPortInfo &info)
        : QSerialPort(info)
    {
        conn();
    }
private slots:
    void slotReadyRead();
signals:
    void sigReadyRead(qscom &sp);

private:
    void conn()
    {
        connect(this, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
    }
    void disc()
    {
        disconnect(this, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
    }
};

class qscoms : public QObject
{
    Q_OBJECT
public:
    enum qscomsRet { SUCCESS = 0, ERROR_OPEN_FAILED, ERROR_NO_FAOUND, ERROR_WRITE_FAILED, ERROR_PARAM };
    struct Sph {
        QSerialPortInfo info;
        qscom *sp;
        QString recBuf;
        bool cached = false;
    };
    struct PortConfig {
        qscom::BaudRate baudRate;
        qscom::DataBits dataBits;
        qscom::Parity parity;
        qscom::StopBits stopBits;
        qscom::FlowControl flowCtrl;
    };
    struct PortInfo {
        QString name;
        QString description;
    };

    qscoms(QObject *parent = nullptr);
    ~qscoms();
    QList<QSerialPortInfo> &reflush();
    qscomsRet open(const QString &name, const PortConfig &pc);
    qscomsRet close(const QString &name);
    bool isOpen(const QString &name);
    qscomsRet send(const QString &name, const QString &data);
    void setCached(const QString &name, bool cached);
private slots:
    void slotReadyRead(qscom &sp);
signals:
    void sigSpDataReceive(QString name, QString str);

private:
    QList<QSerialPortInfo> spsInfo;
    QMap<QString, Sph> sps;
    QTimer *timer;

    void clear();
    QSerialPortInfo *isValid(const QString &name);
};

#endif /* __HJ_QSCOM_H__ */
